#include "FPSComponent.h"

IEngineComponentRegistry fpsComponentRegistry("FPSComponent", FPSComponent::Deserialize);

FPSComponent::FPSComponent(void)
{
	pDevice = NULL;
	pFont = NULL;

	updateInterval = 20;
    updateTimes = new LONGLONG[updateInterval];
	ZeroMemory(updateTimes, sizeof(float)*updateInterval);
	index = 0;
	fps = 0;
}

FPSComponent::~FPSComponent(void)
{
	UnloadGraphicsContent();
	delete updateTimes;
}

HRESULT FPSComponent::LoadGraphicsContent(EnginePointer<ID3D10Device> &pDevice)
{
	HRESULT hr = S_OK;

	this->pDevice = pDevice;

	hr = D3DX10CreateFont(pDevice, 14, 0, FW_NORMAL, 1, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, L"Arial", &pFont);
	if (FAILED(hr)) return hr;

	return S_OK;
}

void FPSComponent::UnloadGraphicsContent()
{
	if (pFont != NULL) pFont->Release();
	pFont = NULL;
	pDevice = NULL;
}

void FPSComponent::Update(LONGLONG timeElapsed)
{
	updateTimes[index] = timeElapsed;

	index = (++index) % updateInterval;

	LONGLONG timeSinceLastUpdate = 0;
	for (unsigned int i = 0; i < updateInterval; i++)
	{
		timeSinceLastUpdate += updateTimes[i];
	}

	fps = updateInterval / (timeSinceLastUpdate / 1000000.0f); //mean fps over updateIntrval
}

void FPSComponent::Draw()
{
	WCHAR fpsText[10];
	swprintf_s(fpsText, _countof(fpsText), L"%.0f fps", fps);

	RECT rect;
	SetRect(&rect, 10, 10, 0, 0);

	pFont->DrawText(NULL, fpsText, -1, &rect, DT_NOCLIP, D3DXCOLOR(1,0,0,1));
}

void FPSComponent::Serialize(EnginePointer<ISerializerWriteContext>& context, char* name)
{
	context->StartItem(name, "FPSComponent", "1.0");
	context->SerializeProperty("componentId", this->componentId);
	context->EndItem(name);
}

IEngineComponent* FPSComponent::Deserialize(EnginePointer<ISerializerReadContext>& context)
{
	FPSComponent* fps = new FPSComponent();
	int index = 0;
	char* childName = context->ChildName(index);

	while (childName != NULL)
	{
		if (strcmp(childName, "componentId") == 0)
		{
			fps->componentId = context->ChildValueAsULongLong(index);
		}
		childName = context->ChildName(++index);
	}
	
	return fps;
}